﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ModeloGaleriaNET;
using CADs;
using AvalonDock;
using System.ComponentModel;
using SeguridadGaleria;
using Xceed.Wpf.Toolkit;

namespace GaleriaNET
{
    /// <summary>
    /// Lógica de interacción para ucObraData.xaml
    /// </summary>
    public partial class ucObraData : UserControl
    {
        #region Atributos y propiedades de la clase
        private string[] permisos = new string[] { TiposRoles.CREAR_OBRA, TiposRoles.MODIFICAR_DATOS_OBRA,
            TiposRoles.ELIMINAR_OBRA, TiposRoles.ASIGNAR_OBRAS_CLIENTES};
        /// <summary>
        /// Título de la ventana que se mostrará en la aplicación
        /// </summary>
        private readonly string title;
        /// <summary>
        /// Indica si la venta ha sido cargada ya
        /// </summary>
        private bool loaded;
        /// <summary>
        /// Obra sobre la que se trabaja en caso de que no se esté creando una nueva
        /// </summary>
        private Obra obra;
        /// <summary>
        /// CAD que realizará las operaciones de la obra sobre la base de datos
        /// </summary>
        private ObraCAD oCAD;
        /// <summary>
        /// Color inicial del borde de los elementos del formulario
        /// </summary>
        private Brush brushNormal;
        /// <summary>
        /// Indica si la operación realizada ha terminado con éxito
        /// </summary>
        private bool success;
        /// <summary>
        /// Nombre de la obra con la que se abre el formulario
        /// </summary>
        private string originalNombre;
        /// <summary>
        /// Nombre del autor de la obra con la que se abre el formulario
        /// </summary>
        private string originalAutor;
        /// <summary>
        /// Año de la obra con la que se abre el formulario
        /// </summary>
        private int originalAnyo;
        /// <summary>
        /// Propietario de la obra con la que se abre el formulario
        /// </summary>
        private int originalProp;
        /// <summary>
        /// Estado de la obra con la que se abre el formulario
        /// </summary>
        private int originalEstado;
        private BackgroundWorker worker;
        private Dictionary<string, bool> permisosDatos;
        private string usuario;
        private IAuditoria auditoria;

        /// <summary>
        /// Obtiene el título del formulario
        /// </summary>
        public string Title
        {
            get { return title; }
        }

        /// <summary>
        /// Obtiene o establece el CAD con el que se realizarán operaciones sobre la base de datos
        /// </summary>
        public ObraCAD ObraCAD
        {
            get { return oCAD == null ? new ObraCAD() : oCAD; }
            set { oCAD = value; }
        }
        #endregion

        #region Construcción, carga e inicialización
        /// <summary>
        /// Constructor por defecto de la clase ucObraData
        /// </summary>
        public ucObraData(string u)
        {
            InitializeComponent();
            lbTitulo.Content = title = "Creación de nueva obra";
            loaded = false;
            obra = null;
            usuario = u;
            worker = new BackgroundWorker();
            worker.DoWork += worker_DoWork;
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
            auditoria = new AuditoriaBD();
        }

        /// <summary>
        /// Constructor sobrecargado de la clase ucObraData
        /// </summary>
        /// <param name="o">Obra con la que se trabajará en el formulario</param>
        public ucObraData(Obra o, string u)
        {
            InitializeComponent();
            lbTitulo.Content = title = "Datos de " + o.Nombre;
            loaded = false;
            obra = o;
            usuario = u;
            worker = new BackgroundWorker();
            worker.DoWork += worker_DoWork;
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
            auditoria = new AuditoriaBD();
        }

        /// <summary>
        /// Evento de carga del formulario.
        /// Sólo entrará al código la primera vez que se ejecute.
        /// </summary>
        /// <param name="sender">Objeto que lanza el evento</param>
        /// <param name="e">Argumentos del evento</param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            int anyo;

            if (!loaded) // Si no ha sido cargado ya...
            {
                brushNormal = tbNombre.BorderBrush;
                tbNombre.Focus();
                
                if (obra == null)
                {
                    btBorrar.Visibility = Visibility.Hidden;
                    gridBtEditar.Visibility = Visibility.Hidden;
                    lbListado.Visibility = Visibility.Hidden;
                    dgPropietarios.Visibility = Visibility.Hidden;
                    originalAutor = originalNombre = string.Empty;
                    originalEstado = originalAnyo = originalProp = -1;
                }
                else
                {
                    gridBotones.Visibility = Visibility.Hidden;
                    tbAnyo.IsEnabled = tbAutor.IsEnabled = tbNombre.IsEnabled =
                        cbAntesCristo.IsEnabled = cbPropietario.IsEnabled = cbEstadoConservacion.IsEnabled = false;

                    originalNombre = tbNombre.Text = obra.Nombre;
                    originalAutor = tbAutor.Text = obra.Autor;

                    originalAnyo = anyo = obra.Anyo;
                    if (anyo < 0)
                    {
                        tbAnyo.Text = anyo.ToString().Replace("-", "");
                        cbAntesCristo.SelectedIndex = 1;
                    }
                    else
                    {
                        tbAnyo.Text = anyo.ToString();
                        cbAntesCristo.SelectedIndex = 0;
                    }

                    switch (obra.EstadoConservacion)
                    {
                        case "original":
                            originalEstado = cbEstadoConservacion.SelectedIndex = 0;
                            break;
                        case "deteriorado":
                            originalEstado = cbEstadoConservacion.SelectedIndex = 1;
                            break;
                        case "restaurado":
                            originalEstado = cbEstadoConservacion.SelectedIndex = 2;
                            break;
                    }

                    cbPropietario.DisplayMemberPath = "NombrePropietarioActual";
                    cbPropietario.SelectedValuePath = "IdPropietarioActual";
                    cbPropietario.Items.Add(new { obra.IdPropietarioActual, obra.NombrePropietarioActual });
                    cbPropietario.SelectedIndex = cbPropietario.Items.Count - 1;
                    dgPropietarios.ItemsSource = obra.PropietariosAnteriores;
                }

                if (!worker.IsBusy)
                {
                    _busyIndicator.IsBusy = true;
                    worker.RunWorkerAsync();
                }

                success = false;
                loaded = true;
            }
        }

        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            bool? value;

            permisosDatos = new Dictionary<string, bool>();
            foreach (string s in permisos)
            {
                value = ManejadorRoles.Instance.CanUse(s, usuario);
                if (value != null)
                    permisosDatos.Add(s, value.Value);
            }
        }

        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            bool value, value2, value3;

            if (permisosDatos == null || permisosDatos.Count != permisos.Length)
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("No se han podido obtener los permisos", "Error",
                    MessageBoxButton.OK, MessageBoxImage.Error);
                btBorrar.IsEnabled = btEditar.IsEnabled = btGuardar.IsEnabled = tbAnyo.IsEnabled = cbAntesCristo.IsEnabled = 
                tbNombre.IsEnabled = tbAutor.IsEnabled = cbEstadoConservacion.IsEnabled = cbPropietario.IsEnabled = dgPropietarios.IsEnabled = false;
            }
            else
            {
                if (obra == null) // Solo crear
                {
                    permisosDatos.TryGetValue(TiposRoles.CREAR_OBRA, out value);
                    if (value == false)
                        btGuardar.IsEnabled = btBorrar.IsEnabled = btEditar.IsEnabled = btGuardar.IsEnabled = tbAnyo.IsEnabled = cbAntesCristo.IsEnabled = 
                tbNombre.IsEnabled = tbAutor.IsEnabled = cbEstadoConservacion.IsEnabled = cbPropietario.IsEnabled = dgPropietarios.IsEnabled = false;
                }
                else // Modificar y borrar
                {
                    permisosDatos.TryGetValue(TiposRoles.MODIFICAR_DATOS_OBRA, out value);
                    permisosDatos.TryGetValue(TiposRoles.ELIMINAR_OBRA, out value2);
                    permisosDatos.TryGetValue(TiposRoles.ASIGNAR_OBRAS_CLIENTES, out value3);

                    if (value2 == false && value == false && value3 == false)
                    {
                        btBorrar.IsEnabled = btEditar.IsEnabled = btGuardar.IsEnabled = tbAnyo.IsEnabled = cbAntesCristo.IsEnabled =
                        tbNombre.IsEnabled = tbAutor.IsEnabled = cbEstadoConservacion.IsEnabled = cbPropietario.IsEnabled = dgPropietarios.IsEnabled = false;
                    }
                    else
                    {
                        if (value == false && value3 == false)
                        {
                            btGuardar.IsEnabled = tbAnyo.IsEnabled = cbAntesCristo.IsEnabled =
                            tbNombre.IsEnabled = tbAutor.IsEnabled = cbEstadoConservacion.IsEnabled = cbPropietario.IsEnabled = dgPropietarios.IsEnabled = false;
                        }
                        else
                        {
                            if (value == false)
                            {
                                tbAnyo.IsEnabled = cbAntesCristo.IsEnabled =
                                tbNombre.IsEnabled = tbAutor.IsEnabled = cbEstadoConservacion.IsEnabled = false;
                            }

                            if (value3 == false)
                                cbPropietario.IsEnabled = dgPropietarios.IsEnabled = false;
                        }

                        if (value2 == false)
                            btBorrar.IsEnabled = false;
                    }
                }
            }
            _busyIndicator.IsBusy = false;
        }
        #endregion

        #region Métodos auxiliares
        /// <summary>
        /// Obtiene la instancia de la clase UserWindow donde se contienen todos los formularios
        /// </summary>
        /// <returns>La instancia de UserWindow donde se contienen los formularios</returns>
        private UserWindow GetContainerWindow()
        {
            DockingManager manager;
            manager = ((DocumentContent)(this.Parent)).Manager;
            return (UserWindow)(((Grid)(manager.Parent)).Parent);
        }

        /// <summary>
        /// Método que, según el estado de la obra seleccionado, realiza un filtrado para adecuarlo a la base de datos
        /// </summary>
        /// <returns>Estado de la obra filtrado para la base de datos</returns>
        private string ProcesarEstadoObra()
        {
            string salida;

            switch (cbEstadoConservacion.SelectedIndex)
            {
                case 0:
                    salida = "original";
                    break;
                case 1:
                    salida = "deteriorado";
                    break;
                case 2:
                    salida = "restaurado";
                    break;
                default:
                    salida = string.Empty;
                    break;
            }

            return salida;
        }

        /// <summary>
        /// Método que se asegura de que los campos necesarios estén rellenos y de que los valores introducidos sean correctos
        /// </summary>
        /// <returns>True en caso de que todo sea correcto y false en caso contrario</returns>
        private bool AreCamposCorrectos()
        {
            bool salida = true;
            ToolTip t;
            int anyo;

            // Comprobamos que los campos obligatorios estén llenos
            if (string.IsNullOrWhiteSpace(tbNombre.Text) || string.IsNullOrWhiteSpace(tbAutor.Text) ||
                string.IsNullOrWhiteSpace(tbAnyo.Text) || cbEstadoConservacion.SelectedIndex == -1)
            {
                t = new ToolTip();
                t.Content = "Este campo no puede estar vacío";

                if (string.IsNullOrWhiteSpace(tbNombre.Text))
                {
                    tbNombre.BorderBrush = new SolidColorBrush(Colors.Red);
                    tbNombre.ToolTip = t;
                }
                if (string.IsNullOrWhiteSpace(tbAutor.Text))
                {
                    tbAutor.BorderBrush = new SolidColorBrush(Colors.Red);
                    tbAutor.ToolTip = t;
                }
                if (string.IsNullOrWhiteSpace(tbAnyo.Text))
                {
                    tbAnyo.BorderBrush = new SolidColorBrush(Colors.Red);
                    tbAnyo.ToolTip = t;
                }
                if (cbEstadoConservacion.SelectedIndex == -1)
                {
                    cbEstadoConservacion.BorderBrush = new SolidColorBrush(Colors.Red);
                    cbEstadoConservacion.ToolTip = t;
                }
                salida = false;
            }
            else
            {
                // Miramos que el año esté correcto
                if (!Validacion.IsPositiveInteger(tbAnyo.Text))
                {
                    tbAnyo.BorderBrush = new SolidColorBrush(Colors.Red);
                    t = new ToolTip();
                    t.Content = "Formato de año incorrecto";
                    tbAnyo.ToolTip = t;
                    salida = false;
                }
                else
                {
                    // Si los datos del form están correctos, mira que no exista una obra idéntica (si es una obra nueva)
                    if (obra == null)
                    {
                        anyo = cbAntesCristo.SelectedIndex == 0 ? Convert.ToInt32(tbAnyo.Text) : -1 * Convert.ToInt32(tbAnyo.Text);
                        if (ObraCAD.GetObraByNombreAutorAnyo(tbNombre.Text, tbAutor.Text, anyo) != null)
                        {
                            t = new ToolTip();
                            t.Content = "Ya existe una obra idéntica en la base de datos";
                            tbAnyo.BorderBrush = new SolidColorBrush(Colors.Red);
                            tbNombre.BorderBrush = new SolidColorBrush(Colors.Red);
                            tbAutor.BorderBrush = new SolidColorBrush(Colors.Red);
                            tbAnyo.ToolTip = tbAutor.ToolTip = tbNombre.ToolTip = t;
                            salida = false;
                        }
                    }
                }
            }

            return salida;
        }

        /// <summary>
        /// Método que indica si ha habido cambios en los valores del formulario
        /// </summary>
        /// <returns>True si ha habido cambios y False en caso contrario</returns>
        private bool HasChanges()
        {
            int anyo;
            anyo = string.IsNullOrWhiteSpace(tbAnyo.Text) ? originalAnyo : (cbAntesCristo.SelectedIndex == 0 ? Convert.ToInt32(tbAnyo.Text) : Convert.ToInt32(tbAnyo.Text) * -1);

            if (!originalNombre.Equals(tbNombre.Text) || !originalAutor.Equals(tbAutor.Text) ||
                originalEstado != cbEstadoConservacion.SelectedIndex || originalAnyo != anyo)
                return true;

            // Como es más peliagudo, se hace aparte la comprobación de si el usuario ha cambiado
            if (cbPropietario.ItemsSource != null && (originalProp != cbPropietario.SelectedIndex))
                return true;

            return false;
        }

        /// <summary>
        /// Método que busca un tipo de documento entre todos los abierto en la aplicación
        /// </summary>
        /// <param name="t">Tipo de documento a buscar</param>
        /// <returns>El documento encontrado o NULL si no existe</returns>
        private DocumentContent FindDocumentContent(Type t)
        {
            DockingManager manager;

            manager = ((DocumentContent)this.Parent).Manager;
            // Buscamos si hay abierta una instancia del documento a abrir
            foreach (AvalonDock.DocumentContent doc in manager.Documents)
            {
                if (doc.Content.GetType() == t)
                    return doc;
            }
            return null;
        }

        /// <summary>
        /// Método que cierra el formulario actual
        /// </summary>
        private void Close()
        {
            ((DocumentContent)this.Parent).Close();
        }

        /// <summary>
        /// Evento lanzado al cerrar el formulario
        /// </summary>
        /// <param name="sender">Objeto que lanza el evento</param>
        /// <param name="e">Argumentos del evento</param>
        private void ClosingDocument(object sender, CancelEventArgs e)
        {
            if (!success)
            {
                if (HasChanges())
                {
                    if (Xceed.Wpf.Toolkit.MessageBox.Show("¿Desea salir sin aplicar los cambios?", "Salir",
                        MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
                        e.Cancel = true;
                }
            }
        }

        /// <summary>
        /// Método que añade eventos al formulario
        /// </summary>
        public void AddEventHandler()
        {
            ((DocumentContent)this.Parent).Closing += ClosingDocument;
        }
        #endregion

        #region Eventos de los controles del formulario
        /// <summary>
        /// Evento lanzado al darle el foco a uno de los controles del formulario.
        /// Quita el Tooltip de los controles y pone el borde normal.
        /// </summary>
        /// <param name="sender">Control que lanza el evento</param>
        /// <param name="e">Argumentos del evento</param>
        private void tbNombre_GotFocus(object sender, RoutedEventArgs e)
        {
            tbNombre.BorderBrush = brushNormal;
            tbAnyo.BorderBrush = brushNormal;
            tbAutor.BorderBrush = brushNormal;
            cbEstadoConservacion.BorderBrush = brushNormal;
            cbPropietario.BorderBrush = brushNormal;
            tbNombre.ToolTip = tbAutor.ToolTip = tbAnyo.ToolTip =
                cbEstadoConservacion.ToolTip = cbPropietario.ToolTip = null;
        }

        /// <summary>
        /// Evento lanzado al darle el foco al ComboBox de propietarios.
        /// Llama al evento anterior y carga los posibles propietarios en caso de que no estén cargados ya
        /// </summary>
        /// <param name="sender">Control que lanza el evento</param>
        /// <param name="e">Argumentos del evento</param>
        private void cbPropietario_GotFocus(object sender, RoutedEventArgs e)
        {
            int user;
            List<Object> lista;
            Cliente c;
            List<Cliente> aux;

            tbNombre_GotFocus(sender, e);
            if (cbPropietario.ItemsSource == null)
            {
                c = new Cliente();
                aux = new List<Cliente>();
                c.Nombre = "-- Sin propietario --";
                c.Id = 0;
                aux.Add(c);
                lista = new List<object>();
                lista.AddRange(aux.Select(cl => new { cl.Id, cl.ApellidosNombre }));

                if (obra == null)
                {
                    lista.AddRange(new ClienteCAD().GetClientesIdNombre());
                    cbPropietario.ItemsSource = lista;
                    cbPropietario.DisplayMemberPath = "ApellidosNombre";
                    cbPropietario.SelectedValuePath = "Id";
                    cbPropietario.SelectedIndex = -1;
                }
                else
                {
                    user = Convert.ToInt32(cbPropietario.SelectedValue);
                    cbPropietario.Items.Clear();
                    lista.AddRange(new ClienteCAD().GetClientesIdNombre());
                    cbPropietario.ItemsSource = lista;
                    cbPropietario.DisplayMemberPath = "ApellidosNombre";
                    cbPropietario.SelectedValuePath = "Id";

                    for (int i = cbPropietario.Items.Count - 1; i >= 0; i--)
                    {
                        originalProp = cbPropietario.SelectedIndex = i;
                        if (Convert.ToInt32(cbPropietario.SelectedValue) == user)
                            break;
                    }
                }
            }
        }

        /// <summary>
        /// Evento lanzado al clicar sobre el botón de guardar.
        /// Añade la nueva obra a la base de datos o modifica en la misma la obra que se esté editando
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btGuardar_Click(object sender, RoutedEventArgs e)
        {
            Obra o;
            ClientesPropietariosObras cpo, nuevo;
            ucObras obras;
            DocumentContent padre;
            List<ClientesPropietariosObras> aux;
            int uId, zona;
            List<string> camposModificados;

            uId = Convert.ToInt32(Utilities.FindUsuarioData(typeof(UserWindow), this, "Id"));
            zona = Utilities.GetZonaHoraria();

            if (obra == null) // Nueva obra
            {
                if (AreCamposCorrectos())
                {
                    o = new Obra();
                    o.Autor = tbAutor.Text;
                    o.Nombre = tbNombre.Text;
                    o.Anyo = cbAntesCristo.SelectedIndex == 0 ? Convert.ToInt32(tbAnyo.Text) : Convert.ToInt32(tbAnyo.Text) * -1;
                    o.EstadoConservacion = ProcesarEstadoObra();
                    o.UsuarioAlta = GetContainerWindow().Usuario.Id;
                    o.Activo = true;

                    // Si se selecciona propietario...
                    if (cbPropietario.ItemsSource != null && cbPropietario.SelectedIndex != -1 && cbPropietario.SelectedIndex != 0)
                    {
                        cpo = new ClientesPropietariosObras();
                        cpo.Cliente = Convert.ToInt32(cbPropietario.SelectedValue);
                        cpo.Obras = o;
                        cpo.FechaInicio = DateTime.UtcNow;
                        cpo.ZonaFechaInicio = zona;
                        cpo.FechaFin = null;
                        cpo.ZonasFechaFin = null;
                    }

                    if (success = ObraCAD.GuardarNuevaObra(o))
                    {
                        Xceed.Wpf.Toolkit.MessageBox.Show("Obra creada con éxito",
                            "Obra creada", MessageBoxButton.OK, MessageBoxImage.Information);
                        auditoria.Mensaje(new object[] { o.Id },
                                TiposAuditoria.Ordinal(TiposAuditoria.TIPO_AUDITORIA.CREAR_OBRA), uId);
                        System.Threading.Thread.Sleep(1000);
                        if ((padre = (DocumentContent)(FindDocumentContent(typeof(ucObras)))) != null)
                        {
                            obras = (ucObras)(padre.Content);
                            obras.ActualizarDataGrid();
                            Close();
                        }
                    }
                    else
                    {
                        Xceed.Wpf.Toolkit.MessageBox.Show("No se ha podido crear la obra",
                            "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        auditoria.Mensaje(new object[] { o.Id },
                                TiposAuditoria.Ordinal(TiposAuditoria.TIPO_AUDITORIA.ERROR_CREAR_OBRA), uId);
                        System.Threading.Thread.Sleep(1000);
                        return;
                    }
                }
            }
            else // Modificar obra
            {
                // Si tiene cambios, si no close()
                if (HasChanges())
                {
                    if (AreCamposCorrectos())
                    {
                        camposModificados = new List<string>();

                        if (obra.Autor.Equals(tbAutor.Text) == false)
                            camposModificados.Add("autor");
                        if (obra.Nombre.Equals(tbNombre.Text) == false)
                            camposModificados.Add("nombre");
                        if (obra.Anyo != (cbAntesCristo.SelectedIndex == 0 ? Convert.ToInt32(tbAnyo.Text) : Convert.ToInt32(tbAnyo.Text) * -1))
                            camposModificados.Add("año");
                        if (obra.EstadoConservacion.Equals(ProcesarEstadoObra()) == false)
                            camposModificados.Add("estado de conservación");

                        obra.Autor = tbAutor.Text;
                        obra.Nombre = tbNombre.Text;
                        obra.Anyo = cbAntesCristo.SelectedIndex == 0 ? Convert.ToInt32(tbAnyo.Text) : Convert.ToInt32(tbAnyo.Text) * -1;
                        obra.EstadoConservacion = ProcesarEstadoObra();

                        // Se ha cambiado el propietario de la obra, se crea una relación nueva
                        if (cbPropietario.ItemsSource != null && (originalProp != cbPropietario.SelectedIndex))
                        {
                            camposModificados.Add("propietario");
                            // Cogemos la relación actual
                            aux = obra.ClientesPropietariosObras.Where(c => c.FechaFin == null).ToList();
                            cpo = aux == null || aux.Count == 0 ? null : aux.First();

                            if (cpo != null)
                            {
                                cpo.FechaFin = DateTime.UtcNow;
                                cpo.ZonaFechaFin = zona;
                            }

                            if (cbPropietario.SelectedIndex != 0)
                            {
                                // Creamos el nuevo
                                nuevo = new ClientesPropietariosObras();
                                nuevo.Cliente = Convert.ToInt32(cbPropietario.SelectedValue);
                                nuevo.Obras = obra;
                                nuevo.FechaInicio = DateTime.UtcNow;
                                nuevo.ZonaFechaInicio = zona;
                                nuevo.FechaFin = null;
                                nuevo.ZonaFechaFin = null;
                            }
                        }

                        if (success = ObraCAD.GuardarCambios())
                        {
                            Xceed.Wpf.Toolkit.MessageBox.Show("Obra modificada con éxito",
                                    "Obra modificada", MessageBoxButton.OK, MessageBoxImage.Information);
                            auditoria.Mensaje(new object[] { Utilities.ListToString(camposModificados, ", "), obra.Id },
                                TiposAuditoria.Ordinal(TiposAuditoria.TIPO_AUDITORIA.MODIFICAR_DATOS_OBRA), uId);
                            System.Threading.Thread.Sleep(1000);
                            if ((padre = (DocumentContent)(FindDocumentContent(typeof(ucObras)))) != null)
                            {
                                obras = (ucObras)(padre.Content);
                                obras.ActualizarDataGrid();
                                Close();
                            }
                        }
                        else
                        {
                            Xceed.Wpf.Toolkit.MessageBox.Show("No se ha podido modificar la obra",
                                "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                            auditoria.Mensaje(new object[] { Utilities.ListToString(camposModificados, ", "), obra.Id },
                                TiposAuditoria.Ordinal(TiposAuditoria.TIPO_AUDITORIA.ERROR_MODIFICAR_DATOS_OBRA), uId);
                            System.Threading.Thread.Sleep(1000);
                            return;
                        }
                    }
                }
                else
                {
                    Xceed.Wpf.Toolkit.MessageBox.Show("No se ha realizado ningún cambio",
                        "Salir sin cambios", MessageBoxButton.OK, MessageBoxImage.Information);
                    Close();
                }
            }
        }

        /// <summary>
        /// Evento lanzado al clicar sobre el botón de borrar.
        /// Pide confirmación de ello y borra la obra actual.
        /// </summary>
        /// <param name="sender">Control que lanza el evento</param>
        /// <param name="e">Argumentos del evento</param>
        private void btBorrar_Click(object sender, RoutedEventArgs e)
        {
            ucObras obras;
            DocumentContent padre;
            int uId;

            if (Xceed.Wpf.Toolkit.MessageBox.Show("¿Está seguro de que desea borrar esta obra?\nEsta acción no se puede deshacer",
                    "Borrar obra", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                uId = Convert.ToInt32(Utilities.FindUsuarioData(typeof(UserWindow), this, "Id"));
                if (success = ObraCAD.BorrarObra(obra))
                {
                    Xceed.Wpf.Toolkit.MessageBox.Show("Obra borrada con éxito",
                        "Obra borrada", MessageBoxButton.OK, MessageBoxImage.Information);
                    auditoria.Mensaje(new object[] { obra.Id }, TiposAuditoria.Ordinal(TiposAuditoria.TIPO_AUDITORIA.BORRAR_OBRA), uId);
                    System.Threading.Thread.Sleep(1000);
                    if ((padre = (DocumentContent)(FindDocumentContent(typeof(ucObras)))) != null)
                    {
                        obras = (ucObras)(padre.Content);
                        obras.ActualizarDataGrid();
                        Close();
                    }
                }
                else
                {
                    Xceed.Wpf.Toolkit.MessageBox.Show("No se ha podido borrar la obra",
                        "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    auditoria.Mensaje(new object[] { obra.Id }, TiposAuditoria.Ordinal(TiposAuditoria.TIPO_AUDITORIA.ERROR_BORRAR_OBRA), uId);
                    System.Threading.Thread.Sleep(1000);
                    return;
                }

            }
            else
                return;
            
        }

        /// <summary>
        /// Evento lanzado al hacer click sobre el botón de cancelar.
        /// Cierra el formulario.
        /// </summary>
        /// <param name="sender">Control que lanza el evento</param>
        /// <param name="e">Argumentos del evento</param>
        private void btCancelar_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        /// <summary>
        /// Evento lanzado al hacer click sobre el botón de editar.
        /// "Descongela" el formulario y permite editar sus datos.
        /// </summary>
        /// <param name="sender">Objeto que lanza el evento</param>
        /// <param name="e">Argumentos del evento</param>
        private void btEditar_Click(object sender, RoutedEventArgs e)
        {
            // Primero, comprobar que la obra no se esté subastando
            if (obra.ClientePropietarioObraActual != null && obra.ClientePropietarioObraActual.SubastaActual != null)
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("No se pueden editar los datos de una obra que se está subastando",
                    "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                gridBtEditar.Visibility = Visibility.Hidden;
                gridBotones.Visibility = Visibility.Visible;
                tbAnyo.IsEnabled = tbAutor.IsEnabled = tbNombre.IsEnabled =
                    cbAntesCristo.IsEnabled = cbPropietario.IsEnabled = cbEstadoConservacion.IsEnabled = true;
            }
        }
        #endregion        
    }
}
